using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

namespace TCC.Framework
{
    public class UIBehaviour : Behaviour
    {
        /// <summary>
        /// 启用动画
        /// </summary>
        [SerializeField]
        private bool enableAnim=false;

        [SerializeField]
        private string uiAnimType;

        private UIAnimBase uIAnim;

        public RectTransform rectTransform => _rt = _rt ?? GetComponent<RectTransform>();

        public bool IsEnableAnim
        {
            get
            {
                if (enableAnim)
                {
                    if (uIAnim == null)
                    {
                        Assembly[] assembly = AppDomain.CurrentDomain.GetAssemblies();
                        for (int i = 0; i < assembly.Length; i++)
                        {
                            Type type = assembly[i].GetType(uiAnimType);
                            if (type != null)
                            {
                                uIAnim = assembly[i].CreateInstance(uiAnimType) as UIAnimBase;
                                break;
                            }
                        }
                    }
                }
                return enableAnim;
            }
            set
            {
                enableAnim = value;
            }
        }

        private RectTransform _rt;
        private Text _text;
        private Dropdown _dropdown;
        private InputField _inputField;
        private Image _image;
        private Slider _slider;
        private Button _button;
        private Scrollbar _scrollbar;
        private ScrollRect _scrollRect;
        private Toggle _toggle;
        private RawImage _rawImage;
        private HorizontalLayoutGroup _horizontalLayoutGroup;

        public override  void Start()
        {
            base.Start();
            if(enableAnim)
            {
                transform.AddTriggerListener(EventTriggerType.PointerDown, OnPointerDown);
                transform.AddTriggerListener(EventTriggerType.PointerUp, OnPointerUP);
            }
        }

        private void OnEnable()
        {
            if(IsEnableAnim)
                uIAnim.EnableAnim(rectTransform);
        }

        private void OnDisable()
        {
            if (IsEnableAnim)
                uIAnim.DisableAnim(rectTransform);
        }

        private void OnDestroy()
        {
            if(IsEnableAnim)
            {
                transform.RemoveTriggerListener(EventTriggerType.PointerDown, OnPointerDown);
                transform.RemoveTriggerListener(EventTriggerType.PointerUp, OnPointerUP);
            }
        }

        private void OnPointerUP(BaseEventData arg0)
        {
            if (IsEnableAnim && uIAnim != null)
                uIAnim.PointerUpAnim(rectTransform);
        }

        private void OnPointerDown(BaseEventData arg0)
        {
            if (IsEnableAnim && uIAnim != null)
                uIAnim.PointerDownAnim(rectTransform);
        }

        /// <summary>
        /// 重置ID 
        /// </summary>
        public void ResetID()
        {
            ID=gameObject.name+ "_" + long.Parse(DateTime.Now.ToString("yyyyMMddhhmmss")).ToString("X");
        }

        #region Button
        /// <summary>
        /// 添加Button点击事件
        /// </summary>
        /// <param name="action"></param>
        public void AddButtonOnClick(UnityAction action)
        {
            (_button = _button ?? GetComponent<Button>()).onClick.AddListener(() =>
            {
                if (IsEnableAnim && uIAnim != null)
                    uIAnim.OnClickAnim(rectTransform);
                action?.Invoke();
            });
        }

        /// <summary>
        /// 移除Button所有点击事件
        /// </summary>
        public void RemoveAllButtonOnClick()
        {
            (_button = _button ?? GetComponent<Button>()).onClick.RemoveAllListeners();
        }

        /// <summary>
        /// 移除Button点击事件
        /// </summary>
        /// <param name="action"></param>
        public void RemoveButtonOnClick(UnityAction action)
        {
            SelfButton.onClick.RemoveListener(action);
        }

        /// <summary>
        /// 先移除所有点击事件后再添加新的点击事件
        /// </summary>
        public void AddAfterClearButtonOnClick(UnityAction action)
        {
            RemoveAllButtonOnClick();
            AddButtonOnClick(action);
        }

        /// <summary>
        /// Button自身
        /// </summary>
        public Button SelfButton => _button = _button ?? GetComponent<Button>();
        #endregion

        #region Dropdown
        /// <summary>
        /// ��������˵�ֵ�ı��¼�
        /// </summary>
        /// <param name="action"></param>
        public void AddDropdownOnValueChanged(UnityAction<int> action)
        {
            (_dropdown = _dropdown ?? GetComponent<Dropdown>()).onValueChanged.AddListener(action);
        }

        /// <summary>
        /// �Ƴ������˵�����ֵ�ı��¼�
        /// </summary>
        /// <param name="action"></param>
        public void RemoveAllDropdownOnValueChanged()
        {
            (_dropdown = _dropdown ?? GetComponent<Dropdown>()).onValueChanged.RemoveAllListeners();
        }

        /// <summary>
        /// �Ƴ������˵�ֵ�ı��¼�
        /// </summary>
        /// <param name="action"></param>
        public void RemoveDropdownOnValueChanged(UnityAction<int> action)
        {
            (_dropdown = _dropdown ?? GetComponent<Dropdown>()).onValueChanged.RemoveListener(action);
        }

        /// <summary>
        /// ��������˵���
        /// </summary>
        /// <param name="text">�ı�</param>
        public void AddDropdownOptios(string text)
        {
            (_dropdown = _dropdown ?? GetComponent<Dropdown>()).options.Add(new Dropdown.OptionData(text));
        }

        /// <summary>
        /// ��������˵���
        /// </summary>
        /// <param name="text">�ı�</param>
        public void AddDropdownOptios(string text, Sprite imag)
        {
            (_dropdown = _dropdown ?? GetComponent<Dropdown>()).options.Add(new Dropdown.OptionData(text, imag));
        }

        /// <summary>
        /// ��������˵���
        /// </summary>
        public void AddDropdownOptios(Sprite imag)
        {
            (_dropdown = _dropdown ?? GetComponent<Dropdown>()).options.Add(new Dropdown.OptionData(imag));
        }

        /// <summary>
        /// ��������˵���
        /// </summary>
        public void AddDropdownOptios(Dropdown.OptionData optionData)
        {
            (_dropdown = _dropdown ?? GetComponent<Dropdown>()).options.Add(optionData);
        }

        /// <summary>
        /// ��������˵���
        /// </summary>
        /// <param name="optionData"></param>
        public void ClearDropdownOptios()
        {
            (_dropdown = _dropdown ?? GetComponent<Dropdown>()).options.Clear();
        }

        public void SetDropdownValue(int value) => _dropdown.value = value;
        #endregion

        #region Text
        /// <summary>
        ///设置Text文本内容
        /// </summary>
        /// <param name="text"></param>
        public void SetTextStr(string text)
        {
            _text = _text ?? GetComponent<Text>();
            if (_text)
                _text.text = text;
        }

        /// <summary>
        /// Text内容
        /// </summary>
        /// <returns></returns>
        public string TextValue {
            get => (_text = _text ?? GetComponent<Text>())?.text;
            set => SetTextStr(value);
        }

        /// <summary>
        /// 获取文本在本地化语言配置表的编号
        /// </summary>
        /// <returns></returns>
        public int GetLanguageId()
        {
            _text = _text ?? GetComponent<Text>();
            if (_text)
                return (_text as LocalizedLanguageText) == null ? -1 : (_text as LocalizedLanguageText).lacalizedLanguageId;
            else
                return -1;
        }

        /// <summary>
        /// 设置字体颜色
        /// </summary>
        /// <param name="color"></param>
        public void SetTextColor(Color color)
        {
            if (SelfText)
                SelfText.color = color;
        }

        public Text SelfText => _text = _text ?? GetComponent<Text>();
        #endregion

        #region Image
        public Color ImaColor
        {
            get => (_image = _image ?? GetComponent<Image>()).color;
            set
            {
                if ((_image = _image ?? GetComponent<Image>()) != null)
                    _image.color = value;
            }
        }

        public void SetSprite(Sprite sprite)
        {
            (_image = _image ?? GetComponent<Image>()).sprite = sprite;
        }

        public void SetFillAmount(float v)
        {
            SelfImage.fillAmount = v;
        }

        public Image SelfImage => _image = _image ?? GetComponent<Image>();
        #endregion

        #region Slider
        public void SetSliderValue(float v) => (_slider = _slider ?? GetComponent<Slider>()).value = v;

        public void AddSliderOnValueChanged(UnityAction<float> action)
        {
            (_slider = _slider ?? GetComponent<Slider>())?.onValueChanged.AddListener(action);
        }
        #endregion

        #region InputField
        public string InputFieldText
        {
            get => (_inputField = _inputField ?? GetComponent<InputField>()).text;
            set => (_inputField = _inputField ?? GetComponent<InputField>()).text = value;
        }

        public void AddInputFieldOnValueChange(UnityAction<string> action)=>
            (_inputField = _inputField ?? GetComponent<InputField>())?.onValueChanged.AddListener(action);

        public void RemoveInputFieldOnValueChange(UnityAction<string> action)=>
            (_inputField = _inputField ?? GetComponent<InputField>())?.onValueChanged.RemoveListener(action);

        public void RemoveAllInputFieldOnValueChange() =>
            (_inputField = _inputField ?? GetComponent<InputField>())?.onValueChanged.RemoveAllListeners();

        public void AddInputFieldOnEndEdit(UnityAction<string> action) =>
        (_inputField = _inputField ?? GetComponent<InputField>())?.onEndEdit.AddListener(action);

        public void RemoveInputFieldOnEndEdit(UnityAction<string> action) =>
            (_inputField = _inputField ?? GetComponent<InputField>())?.onEndEdit.RemoveListener(action);
        #endregion

        #region Scrollbar

        #endregion

        #region Toggle
        public bool IsOn
        {
            get => (_toggle = _toggle ?? GetComponent<Toggle>()).isOn;
            set => (_toggle = _toggle ?? GetComponent<Toggle>()).isOn = value;
        }

        public void AddToggleOnValueChange(UnityAction<bool> action) =>
            (_toggle = _toggle ?? GetComponent<Toggle>())?.onValueChanged.AddListener(action);
        public void RemoveToggleOnValueChange(UnityAction<bool> action)=>
            (_toggle = _toggle ?? GetComponent<Toggle>())?.onValueChanged.RemoveListener(action);

        public void RemoveAllToggleOnValueChange() =>
            (_toggle = _toggle ?? GetComponent<Toggle>())?.onValueChanged.RemoveAllListeners();

        public void AddAfterClearToggleOnValueChange(UnityAction<bool> action)
        {
            RemoveAllToggleOnValueChange();
            AddToggleOnValueChange(action);
        }

        public Toggle SelfToggle => _toggle = _toggle ?? GetComponent<Toggle>();
        #endregion

        #region ScrollView
        public RectTransform Scro_Content
        {
            get => (_scrollRect = _scrollRect ?? GetComponent<ScrollRect>())?.content;
            set => (_scrollRect = _scrollRect ?? GetComponent<ScrollRect>()).content = value;
        }
        #endregion

        #region 通用
        /// <summary>
        /// 获取子物体
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public Transform GetChild(int index) => transform.childCount > 0 ? transform.GetChild(index) : null;

        /// <summary>
        /// 获取gameObject名字
        /// </summary>
        public string ObjName {
            get => gameObject.name;
            set => gameObject.name = value;
        } 
        #endregion
    }
}